﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using Newtonsoft.Json;

namespace SelectedRowsContainer
{
    public partial class ucSelectRows : UserControl
    {
        /// <summary>
        /// 绑定数据的表格控件
        /// </summary>
        public DataGridView GridView { get; set; }

        /// <summary>
        /// 复选框所在的列
        /// </summary>
        public DataGridViewColumn CheckBoxColumn { get; set; }

        /// <summary>
        /// 点击“已勾选xx” 后弹出的窗口显示的列
        /// </summary>
        public List<DataGridViewColumn> ShowColumnName { get; set; }

        /// <summary>
        /// 唯一键所在的列
        /// </summary>
        public DataGridViewColumn KeyColumn { get; set; }

        /// <summary>
        /// 已勾选的行. DataGridViewRow对象
        /// </summary>
        public List<DataGridViewRow> SelectedRows { get; set; }

        private List<KeyValuePair<object, object>> SelectedRowPairs { get; set; }

        private DataTable _tableSource;

        public bool IsDataTable { get; set; }

        public ucSelectRows()
        {
            InitializeComponent();
            SelectedRows = new List<DataGridViewRow>();
            SelectedRowPairs = new List<KeyValuePair<object, object>>();
        }

        private void ucSelectRows_Load(object sender, EventArgs e)
        {
            Init();
        }
         
        private void Init()
        {
            if (GridView == null)
            {
                return;
            }

            if (SelectedRows == null)
                SelectedRows = new List<DataGridViewRow>();
            if (SelectedRowPairs == null)
                SelectedRowPairs = new List<KeyValuePair<object, object>>();

            GridView.CellClick += GridView_CellClick;
            GridView.DataBindingComplete += GridView_DataBindingComplete;
        }

        private void GridView_DataBindingComplete(object sender, DataGridViewBindingCompleteEventArgs e)
        {
            CheckBoxInit();
        }

        private void GridView_CellClick(object sender, DataGridViewCellEventArgs e)
        {
            if (e.RowIndex == -1 || e.ColumnIndex == -1)
            {
                return;
            }
            if (CheckBoxColumn != null && e.ColumnIndex == CheckBoxColumn.Index)
            {
                var selected = !(bool)GridView.Rows[e.RowIndex].Cells[e.ColumnIndex].EditedFormattedValue;
                var row = GridView.Rows[e.RowIndex];
                var key = row.Cells[KeyColumn.Index].Value;
                var boundItem = row.DataBoundItem;

                if (selected)
                {
                    if (!HasSelect(key))
                    {
                        // 如果绑定的数据源是data table, 复制data table 的行，将选中的数据源保存在 _tableSource对象上面
                        if (boundItem is DataRowView dataRow)
                        {
                            IsDataTable = true;
                            if (_tableSource == null)
                            {
                                _tableSource = new DataTable();
                                _tableSource = dataRow.DataView.Table.Clone();
                            }

                            _tableSource.ImportRow(dataRow.Row);

                            SelectedRowPairs.Add(new KeyValuePair<object, object>(key, 1));
                        }
                        else
                        {
                            // 非 data table类型，直接用序列化复制对象
                            var valStr = JsonConvert.SerializeObject(boundItem);
                            var copy = JsonConvert.DeserializeObject(valStr, boundItem.GetType());
                            
                            SelectedRowPairs.Add(new KeyValuePair<object, object>(key, copy));
                        }

                        var newRow = row.Clone();
                        SelectedRows.Add((DataGridViewRow)newRow);
                    }
                }
                else if(HasSelect(key))
                {
                    RemoveKey(key);
                    if (IsDataTable)
                    {
                        var index = -1;
                        for (var i = 0; i < _tableSource.Rows.Count; i++)
                        {
                            var rowTs = _tableSource.Rows[i];
                            if (rowTs[KeyColumn.DataPropertyName] != key) continue;
                            index = i;
                            break;
                        }

                        if (index > -1)
                            _tableSource.Rows.RemoveAt(index);
                    }
                }
            }

            UpdateSelectText();
        }

        private bool HasSelect(object key)
        {
            return SelectedRowPairs.Exists(m => m.Key.Equals(key));
        }

        private void RemoveKey(object key)
        {
            if (SelectedRowPairs.Count == 0)
            {
                return;
            }
            var index = -1;
            for (int i = 0; i < SelectedRowPairs.Count; i++)
            {
                if (SelectedRowPairs[i].Key.Equals(key))
                {
                    index = i;
                    break;
                }
            }

            if (index > -1)
            {
                SelectedRowPairs.RemoveAt(index);
            }
        }

        private void lkRowCount_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)
        {
            var form = new frmSelectRowList
            {
                GridView = GridView,
                ShowColumnName = ShowColumnName,
                KeyColumn = KeyColumn,
                StartPosition = FormStartPosition.CenterParent
            };
            if (IsDataTable)
            {
                form.DataSource = _tableSource;
            }
            else if(SelectedRowPairs.Count > 0)
            {
                form.DataSource = SelectedRowPairs;
            }

            form.ShowDialog();

            if (form.RemovedKeys?.Count > 0)
            {
                foreach (var key in form.RemovedKeys)
                {
                    RemoveKey(key);
                }
            }

            UpdateSelectText();
            CheckBoxInit();
        }

        private void lkClear_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)
        {
            SelectedRows.Clear();
            SelectedRowPairs.Clear();
            if (IsDataTable)
            {
                _tableSource?.Rows.Clear();
            }
            UpdateSelectText();
            CheckBoxInit();
        }

        private void UpdateSelectText()
        {
            lkRowCount.Text = $"已选择({SelectedRowPairs.Count})条";
        }

        private void CheckBoxInit()
        {
            if (GridView.Rows.Count == 0)
                return;

            foreach (DataGridViewRow row in GridView.Rows)
            {
                var key = row.Cells[KeyColumn.Index].Value;

                row.Cells[CheckBoxColumn.Index].Value = HasSelect(key) ? 1 : 0;
            }
        }

        public object GetSelectedRows()
        {
            if (IsDataTable)
            {
                return _tableSource;
            }
            else if (SelectedRowPairs?.Count > 0)
            {
                return SelectedRowPairs.Select(m => m.Value).ToList();
            }

            return null;
        }
    }
}
